#include "stdafx.h"
#include "CppUnitTest.h"
#include "..\CExpressionUtil\Expression.h"
#include <math.h>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace CExpression;

namespace CExpressionUtilUnitTest
{
	TEST_CLASS(NodeUnitTest)
	{
	public:

		TEST_METHOD(CAbsFunctionNodeTest)
        {
            Expression exp(TEXT("abs(-1)"));
			Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(1, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CAddNodeTest)
        {
            Expression exp(TEXT("1+1+1+1+2+1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(7, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CAndNodeTest)
        {
            Expression exp(TEXT("true&&false"));
			Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(false, exp.BoolResult());
        }

        TEST_METHOD(CAvgFunctionNodeTest)
        {
            Expression exp(TEXT("avg(2,12)"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(7, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CConstBoolNodeTest)
        {
            Expression exp(TEXT("true"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(true, exp.BoolResult());
        }

        TEST_METHOD(CConstNumberNodeTest)
        {
            Expression exp(TEXT("2"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(2, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CDivisionNodeTest)
        {
            Expression exp(TEXT("4/2"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(2, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CEqualNodeTest)
        {
            Expression exp(TEXT("2==2"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(true, exp.BoolResult());
        }

        TEST_METHOD(CExpFunctionNodeTest)
        {
            Expression exp(TEXT("exp(2)"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(std::exp(2), exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CGreaterOrEqualNodeTest)
        {
            Expression exp(TEXT("2>=1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(true, exp.BoolResult());
        }

        TEST_METHOD(CGreaterThanNodeTest)
        {
            Expression exp(TEXT("2>1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(true, exp.BoolResult());
        }

        TEST_METHOD(CIfElseIfFunctionNodeTest)
        {
            Expression exp(TEXT("IfElseIf(2>1,0,1)"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(0, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CLeftShiftNodeTest)
        {
            Expression exp(TEXT("1<<1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(2, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CLessOrEqualNodeTest)
        {
            Expression exp(TEXT("1<=1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(true, exp.BoolResult());
        }

        TEST_METHOD(CLessThanNodeTest)
        {
            Expression exp(TEXT("1<1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(false, exp.BoolResult());
        }

        TEST_METHOD(CLogicAndNodeTest)
        {
            Expression exp(TEXT("0&1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(0, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CLogicNotNodeTest)
        {
            Expression exp(TEXT("~0"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(-1, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CLogicOrNodeTest)
        {
            Expression exp(TEXT("0|1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(1, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CMultiplicationNodeTest)
        {
            Expression exp(TEXT("2*10"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(20, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CNegativeNodeTest)
        {
            Expression exp(TEXT("-1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(-1, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CNotNodeTest)
        {
            Expression exp(TEXT("!true"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(false, exp.BoolResult());
        }

        TEST_METHOD(COrNodeTest)
        {
            Expression exp(TEXT("true||false"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Boolean),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(true, exp.BoolResult());
        }

        TEST_METHOD(CPositiveNodeTest)
        {
            Expression exp(TEXT("+2"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(2, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CRightShiftNodeTest)
        {
            Expression exp(TEXT("2>>1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(1, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CRoundFunctionNodeTest)
        {
            Expression exp(TEXT("round(1.12,1)"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(1.1, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CSubtractNodeTest)
        {
            Expression exp(TEXT("10-1"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(9, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CSumFunctionNodeTest)
        {
            Expression exp(TEXT("sum(1,1,1,1,1)"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(5, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CTruncFunctionNodeTest)
        {
            Expression exp(TEXT("trunc(1.1)"));
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(1, exp.DoubleResult(),0.0001);
        }

        TEST_METHOD(CVariableNodeTest)
        {
            Expression exp(TEXT("a+b"));
            exp.SetVariableValue(TEXT("a"), 1.0);
            exp.SetVariableValue(TEXT("b"), 1.0);
            Assert::AreEqual(static_cast<int>(ExecuteRunTimeType::Double),static_cast<int>(exp.ResultType()));
            Assert::AreEqual(2, exp.DoubleResult(),0.0001);
        }

	};
}